package redesign;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.swing.JOptionPane;

import models.asl.Edge;
import models.asl.EdgeType;
import models.asl.Graph;
import models.asl.Node;
import models.asl.NodeType;

public class Redesign {

    public static int subGoalIndex = 1;
    public static void redesignGraph(Graph domainGraph, Map<Node, List<String>> actionContextMap) {
    	
    	//find action in graph
        for(Node node : actionContextMap.keySet()) {
            List<String> contextCondition = actionContextMap.get(node);
            String sgName = JOptionPane.showInputDialog("Input subgal name for action: " + node.getName());
            if(sgName != null && sgName.trim().isEmpty()) {
                sgName = null;
            }
            Node act = domainGraph.findNode(node);
            
            int id = domainGraph.getNextId();
            Node preNode = null;
            for(Edge incomingEdge : act.getInComingEdges()) {
                preNode = domainGraph.findNodeById(incomingEdge.getSourceId());
                //link preNode to subGoal
                for(Edge preNodeOutEdge : preNode.getOutgoingEdges()) {
                    preNodeOutEdge.setDestinationId(id);
                }
                //link act to condition
                incomingEdge.setSourceId(id + 2);
            }
            
            //put subgoal in front
            Node subGoal = new Node(id, "!" + (sgName == null ? "sg" + (subGoalIndex) : sgName), NodeType.SUBGOAL, false, new ArrayList<Edge>(), new ArrayList<Edge>());
            //link subgoal to preNode
            subGoal.getInComingEdges().add(new Edge(preNode.getId(), subGoal.getId(), EdgeType.SEQUENCIALEDGE));
            subGoal.getOutgoingEdges().add(new Edge(subGoal.getId(), id + 1, EdgeType.ALTPLANEDGE));
            Node subGoalAltPlan = new Node(id + 1, "+!" + (sgName == null ? "sg" + (subGoalIndex) : sgName), NodeType.PLAN, false, new ArrayList<Edge>(), new ArrayList<Edge>());
            subGoalAltPlan.getInComingEdges().add(new Edge(id, id + 1, EdgeType.ALTPLANEDGE));
            subGoalAltPlan.getOutgoingEdges().add(new Edge(id + 1, id + 2, EdgeType.SEQUENCIALEDGE));
            Node cond = new Node(id + 2, convertContextConditionToString(contextCondition), NodeType.CONTEXT_CONDITION, false, new ArrayList<Edge>(), new ArrayList<Edge>());
            cond.getInComingEdges().add(new Edge(id + 1, id + 2, EdgeType.SEQUENCIALEDGE));
            cond.getOutgoingEdges().add(new Edge(id + 2, act.getId(), EdgeType.SEQUENCIALEDGE));
            domainGraph.getNodes().add(subGoal);
            domainGraph.getNodes().add(subGoalAltPlan);
            domainGraph.getNodes().add(cond);
            if(sgName == null) {
                subGoalIndex++;
            }
        }
        
    }
    
    private static String convertContextConditionToString(List<String> conditionList) {
        String s = "";
        int count = 0;
        for(String condition : conditionList) {

            if(count++ != 0) {
                s+= "&";
            }
            s += condition;
        }
        return s;
    }
}
